package aliyun

import (
	"context"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/sts"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/google/uuid"
)

// todo 此文件为废弃file.aoscdn.com项目的头像上传接口，在support项目中仿造历史接口的STS授权上传所构造，流量低时可删除

// Sts 公用操作句柄
var StsAttachment = &sts2attachment{
	accessKeyId:     g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.accessId").String(),
	accessKeySecret: g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.accessKey").String(),
	RoleArn:         g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.roleArn").String(),
	RegionId:        g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.regionId").String(),
	Endpoint:        g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.endpointSts").String(),
	Expires:         g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.expires", 3600).Int(),
}

var (
	AttachmentBucket   = g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.bucket").String()
	AttachmentRegionId = g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.regionId").String()
	AttachmentEndpoint = g.Config().MustGet(context.Background(), "app.aliyun.oss.attachment.endpoint").String()
)

// sts2 sts重名 遵从oss命名方式
type sts2attachment struct {
	accessKeyId     string
	accessKeySecret string
	RoleArn         string
	RegionId        string `json:"-"`
	Endpoint        string `json:"-"`
	Expires         int
}

// stsPolicy policy模板
type stsAttachmentPolicy struct {
	Version   string                         `json:"Version"`
	Statement []stsAttachmentPolicyStatement `json:"Statement"`
}

// stsPolicyStatement sts 策略描述
type stsAttachmentPolicyStatement struct {
	Effect   string   `json:"Effect"`
	Action   []string `json:"Action"`
	Resource []string `json:"Resource"`
}

// stsCredential STS临时凭证
type stsAttachmentCredential struct {
	AccessKeySecret string `json:"access_key_secret"`
	Expiration      int    `json:"expiration"`
	AccessKeyId     string `json:"access_key_id"`
	SecurityToken   string `json:"security_token"`
	Bucket          string `json:"bucket"`
	Endpoint        string `json:"endpoint"`
	Region          string `json:"region,omitempty"`
}

var StsAttachmentPolicyAction = stsAttachmentPolicyAction{}

type stsAttachmentPolicyAction struct {
}

func (s *sts2attachment) NewPolicy(resources []string, actions []string) *stsAttachmentPolicy {
	policyStatements := []stsAttachmentPolicyStatement{{
		Effect:   "Allow",
		Action:   actions,
		Resource: resources,
	}}

	return &stsAttachmentPolicy{
		Version:   "1",
		Statement: policyStatements,
	}
}

// GetCredential 获取临时访问凭证
func (s *sts2attachment) GetCredential(policy *stsAttachmentPolicy) (*stsAttachmentCredential, error) {

	// 构建一个阿里云客户端, 用于发起请求。
	client, err := sts.NewClientWithAccessKey(s.RegionId, s.accessKeyId, s.accessKeySecret)
	// 构建请求对象。
	request := sts.CreateAssumeRoleRequest()
	request.RoleArn = s.RoleArn
	request.RoleSessionName = uuid.New().String()
	request.DurationSeconds = requests.NewInteger(s.Expires)
	request.Policy = gconv.String(policy)
	request.Scheme = "https"
	// 发起请求，并得到响应。
	response, err := client.AssumeRole(request)
	if err != nil {
		return nil, err
	}
	credential := &stsAttachmentCredential{
		SecurityToken:   response.Credentials.SecurityToken,
		AccessKeyId:     response.Credentials.AccessKeyId,
		AccessKeySecret: response.Credentials.AccessKeySecret,
		Expiration:      s.Expires,
		Bucket:          AttachmentBucket,
		Endpoint:        AttachmentEndpoint,
		Region:          AttachmentRegionId,
	}
	return credential, nil
}
